<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
            "http://www.w3.org/TR/REC-html40/loose.dtd">
<HTML>
<HEAD>



<META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<META name="GENERATOR" content="hevea 1.08">
<LINK rel="stylesheet" type="text/css" href="umsroot.css">
<TITLE>
Formal definition of clause syntax
</TITLE>
</HEAD>
<BODY >
<A HREF="umsroot141.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="umsroot139.html"><IMG SRC ="contents_motif.gif" ALT="Up"></A>
<A HREF="umsroot143.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
<HR>

<H2 CLASS="section"><A NAME="htoc309">A.3</A>&nbsp;&nbsp;Formal definition of clause syntax</H2><UL>
<LI><A HREF="umsroot142.html#toc169">Comments</A>
<LI><A HREF="umsroot142.html#toc170">Operators</A>
<LI><A HREF="umsroot142.html#toc171">Operator Ambiguities</A>
</UL>

What follows is the specification of the syntax. The terminal symbols are 
written in UPPER CASE or as the character sequence they consist of.
<A NAME="@default1190"></A>
<A NAME="@default1191"></A>
<A NAME="@default1192"></A>
<PRE CLASS="verbatim">
program                 ::=     clause EOCL
                         |      clause EOCL program

clause                  ::=     head
                         |      head rulech goals
                         |      rulech goals

head                    ::=     term_h

goals                   ::=     term_g
                         |      goals , goals
                         |      goals ; goals
                         |      goals -&gt; goals
                         |      goals -&gt; goals ; goals

term_h                  ::=     term_h(0)
                         |      term(1200)

term_g                  ::=     term_g(0)
                         |      term(1200)

term(0)                 ::=      VAR            /* not a term_h */
                         |       attr_var       /* not a term_h */
                         |       ATOM
                         |       structure
                         |       structure_with_fields
                         |       subscript
                         |       list
                         |       STRING         /* not a term_h nor a term_g */
                         |       number         /* not a term_h nor a term_g */
                         |       bterm

term(N)                 ::=     term(0)
                         |      prefix_expression(N)
                         |      infix_expression(N)
                         |      postfix_expression(N)

prefix_expression(N)    ::=     fx(N)   term(N-1)
                         |      fy(N)   term(N)
                         |      fxx(N)  term(N-1)  term(N-1)
                         |      fxy(N)  term(N-1)  term(N)

infix_expression(N)     ::=     term(N-1)  xfx(N)  term(N-1)
                         |      term(N)    yfx(N)  term(N-1)
                         |      term(N-1)  xfy(N)  term(N)

postfix_expression(N)   ::=     term(N-1)  xf(N)
                         |      term(N)    yf(N)

attr_var                ::=     VAR { attributes }
                                /* Note: no space before { */

attributes              ::=     attribute
                         |      attribute , attributes

attribute               ::=     qualified_attribute
                         |      nonqualified_attribute

qualified_attribute     ::=     ATOM : nonqualified_attribute

nonqualified_attribute  ::=     term_a

structure               ::=     functor ( termlist )
                                /* Note: no space before ( */

structure_with_fields   ::=     functor { termlist }
                         |      functor { }
                                /* Note: no space before { */

subscript               ::=     structure list
                         |      VAR list
                                /* Note: no space before list */

termlist                ::=      term_a
                         |       term_a , termlist

list                    ::=     [ listexpr ]
                         |      .(term_a, term_a)

listexpr                ::=     term_a
                         |      term_a | term_a
                         |      term_a , listexpr

term_a                  ::=     term(1200)
                                /* Note: it depends on syntax_options */

number                  ::=     INT
                         |      INTBAS
                         |      INTCHAR
                         |      RAT
                         |      FLOAT
                         |      BREAL

bterm                   ::=     ( clause )
                         |      { clause }

functor                 ::=     ATOM                    /* arity &gt; 0 */

rulech                  ::=     :-
                         |      ?-
</PRE>
<A NAME="toc169"></A>
<H3 CLASS="subsection"><A NAME="htoc310">A.3.1</A>&nbsp;&nbsp;Comments</H3>
There are two types of comments: bracketed comments, which are enclosed
by CM1-CM2 and CM2-CM1, and the end-of-line comment, which is enclosed
by CM and NL. Both types of comment behave as separators.
When the syntax option <EM>nested_comments</EM> is on (the default is off),
bracketed comments can be nested.<BR>
<BR>
<A NAME="toc170"></A>
<H3 CLASS="subsection"><A NAME="htoc311">A.3.2</A>&nbsp;&nbsp;Operators</H3>
<A NAME="@default1193"></A>
In Prolog, the user is able to modify the syntax dynamically by explicitly 
declaring new operators. The builtin <A HREF="../bips/kernel/syntax/op-3.html"><B>op/3</B></A><A NAME="@default1194"></A> performs this 
task. As in Edinburgh Prolog, a lower precedence value means that the
operator binds stronger (1 strongest, 1200 weakest).<BR>
<BR>
Any atom (whether symbolic, alphanumeric, or quoted) can be declared as an
operator. Once an operator has been declared, the parser will accept
the corresponding operator notation, and certain output builtins will
produce the operator notation if possible. There are three classes of
operators: prefix, infix and postfix.
<A NAME="@default1195"></A>
<A NAME="@default1196"></A>
<A NAME="@default1197"></A>
<UL CLASS="itemize"><LI CLASS="li-itemize">
When <CODE>f</CODE> is declared prefix unary (fx or fy),
then the term <CODE>f(X)</CODE> can alternatively be written as <CODE>f X</CODE>.
<LI CLASS="li-itemize">When <CODE>f</CODE> is declared prefix binary (fxx or fxy),
then the term <CODE>f(X,Y)</CODE> can alternatively be written as <CODE>f X Y</CODE>.
<LI CLASS="li-itemize">When <CODE>f</CODE> is declared postfix (xf or yf),
then the term <CODE>f(X)</CODE> can alternatively be written as <CODE>X f</CODE>.
<LI CLASS="li-itemize">When <CODE>f</CODE> is declared infix (xfx, xfy or yfx),
then the term <CODE>f(X,Y)</CODE> can alternatively be written as <CODE>X f Y</CODE>.
</UL>
An operator can belong to more than one class, e.g. the plus sign
is both a prefix and an infix operator at the same time.<BR>
<BR>
In the associativity specification of an operator (e.g. fx, yfx), x
represents an argument whose precedence must be lower than that of the
operator. y represents an argument whose precedence must be lower or
equal to that of the operator. y should be used if one wants to allow
chaining of operators. The position of the y will determine the
grouping within a chain of operators. For example:
<BLOCKQUOTE CLASS="quote"><PRE CLASS="verbatim">
Example declaration        will allow          to stand for
---------------------------------------------------------------
:- op(500,xfx,in).         A in B              in(A,B)
:- op(500,xfy,in).         A in B in C         in(A,in(B,C))
:- op(500,yfx,in).         A in B in C         in(in(A,B),C)
:- op(500,fx ,pre).        pre A               pre(A)
:- op(500,fy ,pre).        pre pre A           pre(pre(A))
:- op(500, xf,post).       A post              post(A)
:- op(500, yf,post).       A post post         post(post(A))
:- op(500,fxx,bin).        bin A B             bin(A,B)
:- op(500,fxy,bin).        bin A bin B C       bin(A,bin(B,C))
</PRE></BLOCKQUOTE>
Operator declarations are usually local to a module, but they can be
exported and imported. The operator visible in a module is either the
local one (if any), an imported one, or a predefined one.
Some operators are pre-defined (see Appendix <A HREF="umsroot146.html#chapopers">B</A> on
page <A HREF="umsroot146.html#chapopers">??</A>). They may be locally redefined if desired.<BR>
<BR>
Note that parentheses are used to build expressions with precedence zero
and thus to override operator declarations<SUP><A NAME="text33" HREF="umsroot139.html#note33">1</A></SUP>.<BR>
<BR>
<A NAME="toc171"></A>
<H3 CLASS="subsection"><A NAME="htoc312">A.3.3</A>&nbsp;&nbsp;Operator Ambiguities</H3>
<A NAME="@default1198"></A>
Unlike the canonical syntax, operator syntax can lead to ambiguities.
<UL CLASS="itemize"><LI CLASS="li-itemize">
<A NAME="@default1199"></A>
For instance, when a prefix operator is followed by an infix or postfix
operator, the prefix is often not meant to be a prefix operator, but
simply the left hand side argument of the following infix or postfix.
In order to decide whether that is the case, ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> uses the operator's
relative precedences and their associativities, and, if necessary,
a two-token lookahead. If this rules out the prefix-interpretation, then
the prefix is treated as a simple atom. In the rare case where this
limited lookahead is not enough to disambigute, the prefix must be
explicitly enclosed in parentheses.<BR>
<BR>
<LI CLASS="li-itemize"><A NAME="@default1200"></A>
Another source of ambiguity are operators which have been declared
both infix and postfix. In this case, ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> uses a one-token
lookahead to check whether the infix-interpretation can be ruled out.
If yes, the operator is interpreted as postfix, otherwise as infix.
Again, in rare cases parentheses may be necessary to enforce the
interpretation as postfix.<BR>
<BR>
<LI CLASS="li-itemize"><A NAME="@default1201"></A>
When a binary prefix operator is followed by an infix operator, then
either of them could be the main functor. Faced with the ambiguity, the
system will prefer the infix interpretation. To force the binary prefix
to be recognised, the infix must be enclosed in parentheses.
</UL>
<HR>
<A HREF="umsroot141.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="umsroot139.html"><IMG SRC ="contents_motif.gif" ALT="Up"></A>
<A HREF="umsroot143.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
</BODY>
</HTML>
